//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Expressions;

namespace OpenLS.Spreadsheet.Parsing
{
#if DEBUG
    [ContractClassFor(typeof (CellNamingConvention))]
    internal abstract class CellNamingConvertionContract : CellNamingConvention
    {
        internal override List<ReferenceToken> ParseRangeReference(ExpressionParser parser)
        {
            Contract.Ensures(Contract.Result<List<ReferenceToken>>() == null || Enumerable.All(
                                                                                    Contract.Result
                                                                                        <List<ReferenceToken>>(),
                                                                                    t => t != null));
            return default(List<ReferenceToken>);
        }

        public override bool TryParse(string s, out CellAddress result)
        {
            Contract.Requires(s != null);
            result = new CellAddress();
            return default(bool);
        }

        public override bool TryParseColumn(string s, out int columnIndex, out int length)
        {
            Contract.Requires(s != null);
            columnIndex = 0;
            length = 0;
            return default(bool);
        }

        internal override CellReferenceToken ParseCellReference(string text)
        {
            Contract.Requires(text != null);
            return default(CellReferenceToken);
        }
    }
#endif

#if DEBUG
    [ContractClass(typeof (CellNamingConvertionContract))]
#endif
    internal abstract class CellNamingConvention
    {
        public abstract bool TryParse(string s, out CellAddress result);
        public abstract bool TryParseColumn(string s, out int columnIndex, out int length);

        public bool TryParseColumn(string s, out int columnIndex)
        {
            Contract.Requires(s != null);

            int length = 0;
            bool result = TryParseColumn(s, out columnIndex, out length);
            if (length != s.Length)
                return false;
            return true;
        }

        public abstract bool RowBeforeColumn { get; }


        internal abstract List<ReferenceToken> ParseRangeReference(ExpressionParser parser);
        internal abstract CellReferenceToken ParseCellReference(string text);

        protected int ParseColumn(string name)
        {
            Contract.Requires(name != null);

            int result;
            int length;
            if (!TryParseColumn(name, out result, out length))
                throw new ArgumentException();
            return result;
        }

        public abstract string GetText(CellReferenceToken token);
        public abstract string GetColumnName(int index, bool locked);
        public abstract string GetRowName(int index, bool locked);
    }
}